from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QPushButton, 
                           QLabel, QFileDialog, QProgressBar,
                           QListWidget, QHBoxLayout, QComboBox,
                           QMessageBox, QListWidgetItem)
from PyQt6.QtCore import Qt, QTimer, pyqtSignal, QObject
from PyQt6.QtGui import QFont
from utils.converter import FileConverter
import os
import threading

class SignalEmitter(QObject):
    progress_signal = pyqtSignal(int)
    error_signal = pyqtSignal(str)
    complete_signal = pyqtSignal()

class PDFToImageConverter(QWidget):
    OUTPUT_FORMATS = {
        'PNG (*.png)': '.png',
        'JPEG (*.jpg)': '.jpg',
        'BMP (*.bmp)': '.bmp'
    }
    
    ZOOM_LEVELS = {
        '100%': 1,  # 默认
        '200%': 2,
        '300%': 3,
        '400%': 4,
        '500%': 5
    }
    
    def __init__(self, title="PDF转图片", description="将PDF文件转换为高清图片格式"):
        super().__init__()
        self.title = title
        self.description = description
        self.selected_file = None  # 只需要一个PDF文件
        self.save_path = ""
        self.output_format = '.png'  # 默认输出格式
        self.zoom_level = 1  # 默认100%
        
        # 创建信号发射器
        self.signal_emitter = SignalEmitter()
        self.signal_emitter.progress_signal.connect(self.on_progress_update)
        self.signal_emitter.error_signal.connect(self.on_error)
        self.signal_emitter.complete_signal.connect(self.on_conversion_complete)
        
        self.init_ui()
    
    def init_ui(self):
        layout = QVBoxLayout(self)
        layout.setContentsMargins(20, 20, 20, 20)
        
        # 标题和说明
        title_label = QLabel(self.title)
        title_label.setFont(QFont("Arial", 16, QFont.Weight.Bold))
        layout.addWidget(title_label)
        
        desc_label = QLabel(self.description)
        desc_label.setStyleSheet("color: #666666;")
        layout.addWidget(desc_label)
        
        # 文件选择区域
        layout.addWidget(self.create_file_section())
        
        # 格式选择区域
        layout.addWidget(self.create_format_section())
        
        # 保存路径选择
        layout.addLayout(self.create_save_section())
        
        # 转换按钮
        layout.addLayout(self.create_convert_section())
        
        # 进度条和状态
        self.progress_bar = QProgressBar()
        self.progress_bar.setStyleSheet("""
            QProgressBar {
                border: 1px solid #CCCCCC;
                border-radius: 4px;
                text-align: center;
            }
            QProgressBar::chunk {
                background-color: #2B579A;
            }
        """)
        self.progress_bar.hide()
        layout.addWidget(self.progress_bar)
        
        self.status_label = QLabel("")
        self.status_label.setStyleSheet("color: #666666;")
        self.status_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(self.status_label)
        
        layout.addStretch()
        
        # 初始化按钮状态
        self.update_convert_button()
    
    def create_file_section(self):
        widget = QWidget()
        layout = QVBoxLayout(widget)
        
        step1 = QLabel("1. 选择PDF文件")
        step1.setFont(QFont("Arial", 11))
        
        file_layout = QHBoxLayout()
        self.select_btn = QPushButton("选择PDF")
        self.select_btn.setStyleSheet("""
            QPushButton {
                background-color: #2B579A;
                color: white;
                padding: 8px 16px;
                border-radius: 4px;
            }
            QPushButton:hover {
                background-color: #1E3F7F;
            }
        """)
        self.select_btn.clicked.connect(self.select_file)
        
        self.file_label = QLabel("未选择文件")
        self.file_label.setStyleSheet("color: #666666;")
        
        file_layout.addWidget(self.select_btn)
        file_layout.addWidget(self.file_label)
        file_layout.addStretch()
        
        layout.addWidget(step1)
        layout.addLayout(file_layout)
        return widget
    
    def create_format_section(self):
        widget = QWidget()
        layout = QVBoxLayout(widget)
        
        step2 = QLabel("2. 选择输出格式")
        step2.setFont(QFont("Arial", 11))
        
        format_layout = QHBoxLayout()
        self.format_combo = QComboBox()
        self.format_combo.addItems(self.OUTPUT_FORMATS.keys())
        self.format_combo.currentTextChanged.connect(self.on_format_changed)
        
        quality_label = QLabel("图片清晰度：")
        self.quality_combo = QComboBox()
        self.quality_combo.addItems(self.ZOOM_LEVELS.keys())
        self.quality_combo.setCurrentText('100%')
        self.quality_combo.currentTextChanged.connect(self.on_quality_changed)
        
        for combo in [self.format_combo, self.quality_combo]:
            combo.setStyleSheet("""
                QComboBox {
                    padding: 5px;
                    border: 1px solid #CCCCCC;
                    border-radius: 4px;
                    min-width: 100px;
                }
            """)
        
        format_layout.addWidget(self.format_combo)
        format_layout.addWidget(quality_label)
        format_layout.addWidget(self.quality_combo)
        format_layout.addStretch()
        
        layout.addWidget(step2)
        layout.addLayout(format_layout)
        return widget
    
    def create_save_section(self):
        save_layout = QHBoxLayout()
        self.save_path_label = QLabel("未选择保存位置")
        self.save_path_label.setStyleSheet("color: #666666;")
        
        self.save_btn = QPushButton("选择路径")
        self.save_btn.setStyleSheet("""
            QPushButton {
                background-color: #2B579A;
                color: white;
                padding: 8px 16px;
                border-radius: 4px;
            }
            QPushButton:hover {
                background-color: #1E3F7F;
            }
        """)
        self.save_btn.clicked.connect(self.select_save_path)
        
        save_layout.addWidget(self.save_path_label)
        save_layout.addWidget(self.save_btn)
        return save_layout
    
    def create_convert_section(self):
        convert_layout = QHBoxLayout()
        convert_layout.addStretch()
        
        self.convert_btn = QPushButton("开始转换")
        self.convert_btn.setMinimumWidth(120)
        self.convert_btn.setStyleSheet("""
            QPushButton {
                background-color: #2B579A;
                color: white;
                padding: 8px 16px;
                border-radius: 4px;
            }
            QPushButton:hover {
                background-color: #1E3F7F;
            }
            QPushButton:disabled {
                background-color: #CCCCCC;
            }
        """)
        self.convert_btn.clicked.connect(self.start_conversion)
        
        self.status_label = QLabel("")
        self.status_label.setStyleSheet("color: #666666;")
        self.status_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        
        convert_layout.addWidget(self.convert_btn)
        return convert_layout
    
    def select_file(self):
        """选择PDF文件"""
        file, _ = QFileDialog.getOpenFileName(
            self,
            "选择PDF文件",
            "",
            "PDF文件 (*.pdf)"
        )
        if file:
            # 确保使用绝对路径，并检查文件是否存在
            abs_path = os.path.abspath(file)
            if os.path.exists(abs_path):
                self.selected_file = abs_path
                self.file_label.setText(os.path.basename(abs_path))
                # 设置默认保存路径为输入文件所在目录
                self.save_path = os.path.dirname(abs_path)
                self.save_path_label.setText(f"保存位置: {self.save_path}")
                self.update_convert_button()
                self.status_label.setText("已选择PDF文件，可以开始转换")
            else:
                QMessageBox.warning(
                    self,
                    "文件错误",
                    f"无法访问文件：{file}\n请确认文件是否存在"
                )
    
    def select_save_path(self):
        """选择保存位置"""
        path = QFileDialog.getExistingDirectory(
            self,
            "选择保存位置",
            "",
            QFileDialog.Option.ShowDirsOnly
        )
        if path:
            # 确保使用绝对路径，并检查目录是否可写
            abs_path = os.path.abspath(path)
            if os.path.exists(abs_path) and os.access(abs_path, os.W_OK):
                self.save_path = abs_path
                self.save_path_label.setText(f"保存位置: {abs_path}")
                self.update_convert_button()
            else:
                QMessageBox.warning(
                    self,
                    "路径错误",
                    f"无法访问或写入目录：{path}\n请确认目录权限"
                )
    
    def update_convert_button(self):
        """更新转换按钮状态"""
        self.convert_btn.setEnabled(
            bool(self.selected_file) and bool(self.save_path)
        )
    
    def start_conversion(self):
        """开始转换"""
        if not self.selected_file or not self.save_path:
            return
        
        self.convert_btn.setEnabled(False)
        self.select_btn.setEnabled(False)
        self.save_btn.setEnabled(False)
        self.progress_bar.show()
        self.progress_bar.setValue(0)
        self.status_label.setText("正在转换...")
        
        # 在新线程中执行转换
        threading.Thread(target=self.convert_file, daemon=True).start()
    
    def convert_file(self):
        """执行文件转换"""
        try:
            # 再次检查文件是否存在
            if not os.path.exists(self.selected_file):
                raise FileNotFoundError(f"找不到文件：{self.selected_file}")
            
            # 检查文件是否可读
            if not os.access(self.selected_file, os.R_OK):
                raise PermissionError(f"无法读取文件：{self.selected_file}")
            
            # 检查保存目录是否可写
            if not os.access(self.save_path, os.W_OK):
                raise PermissionError(f"无法写入目录：{self.save_path}")

            # 获取PDF页数
            pdf_info = FileConverter.get_pdf_info(self.selected_file)
            total_pages = pdf_info['pages']
            
            # 获取选择的输出格式
            format_text = self.format_combo.currentText()
            output_format = self.OUTPUT_FORMATS[format_text]
            
            # 获取文件名（不含扩展名）
            filename = os.path.basename(self.selected_file)
            name = os.path.splitext(filename)[0]
            
            # 转换每一页
            for page in range(total_pages):
                # 构建输出文件名
                if total_pages > 1:
                    output_file = os.path.join(
                        self.save_path, 
                        f"{name}_第{page + 1}页{output_format}"
                    )
                else:
                    output_file = os.path.join(
                        self.save_path, 
                        f"{name}{output_format}"
                    )
                
                # 更新进度
                progress = (page + 1) / total_pages * 100
                self.signal_emitter.progress_signal.emit(int(progress))
                
                # 执行转换
                FileConverter.pdf_to_image(
                    self.selected_file,
                    output_file,
                    page_number=page,
                    zoom=self.zoom_level
                )
            
            # 转换完成
            self.signal_emitter.complete_signal.emit()
            
        except FileNotFoundError as e:
            self.signal_emitter.error_signal.emit(f"文件不存在：{str(e)}")
        except PermissionError as e:
            self.signal_emitter.error_signal.emit(f"权限错误：{str(e)}")
        except Exception as e:
            self.signal_emitter.error_signal.emit(f"转换失败：{str(e)}")
    
    def on_format_changed(self, format_text):
        """处理输出格式改变"""
        self.output_format = self.OUTPUT_FORMATS[format_text]
        self.status_label.setText(f"已选择输出格式: {format_text}")

    def on_quality_changed(self, quality_text):
        """处理清晰度改变"""
        self.zoom_level = self.ZOOM_LEVELS[quality_text]
        self.status_label.setText(f"已选择清晰度: {quality_text}")

    def on_progress_update(self, progress):
        """处理进度更新"""
        self.progress_bar.setValue(progress)

    def on_error(self, error_message):
        """处理错误"""
        QMessageBox.critical(
            self,
            "转换错误",
            error_message
        )
        self.reset_interface()

    def on_conversion_complete(self):
        """处理转换完成"""
        QMessageBox.information(
            self,
            "转换完成",
            f"PDF已成功转换为图片！\n保存位置：{self.save_path}"
        )
        self.reset_interface()

    def reset_interface(self):
        """重置界面状态"""
        self.progress_bar.hide()
        self.progress_bar.setValue(0)
        self.status_label.setText("")
        self.convert_btn.setEnabled(True)
        self.select_btn.setEnabled(True)
        self.save_btn.setEnabled(True)
        self.selected_file = None
        self.save_path = ""
        self.file_label.setText("未选择文件")
        self.save_path_label.setText("未选择保存位置") 
 